package mskruch.gps.matching;

import java.util.Set;
import java.util.TreeSet;

import mskruch.gps.Point;
import mskruch.gps.Position;
import mskruch.gps.Positions;
import mskruch.gps.calculation.Calculations;
import mskruch.gps.calculation.PositionsCalculator;

public class LegacyTrackFinder implements TrackFinder {
    private static final int DEFAULT_DISTANCE_BETWEEN_CHECKPOINTS = 640;

    private mskruch.gps.matching.legacy.TrackFinder tf;
    private Set<Long> roundedTimes = new TreeSet<Long>();

    @Override
    public void setPattern(Position[] pattern) {
        Position first = pattern[0];
        Position last = pattern[pattern.length - 1];
        boolean loop = first.equals(last);

        PositionsCalculator pc = Calculations.newPositionsCalculator().add(pattern);

        int checks = (int) (pc.getDistance() / DEFAULT_DISTANCE_BETWEEN_CHECKPOINTS);
        checks = Integer.valueOf(Math.max(checks, 2));
        Position[] checkPoints = new Positions(pattern).findCheckpoints(checks);

        if (loop) {
            tf = new mskruch.gps.matching.legacy.TrackFinder(first, checkPoints);
        } else {
            tf = new mskruch.gps.matching.legacy.TrackFinder(first, last, checkPoints);
        }
    }

    @Override
    public void setSource(Point[] source) {
        tf.setSource(source);
        roundedTimes.clear();
    }

    @Override
    public Point[] next() {
        Point[] found = tf.next();
        if (found != null) {
            long roundedTime = Math.round((double) found[found.length - 1].getTime() / 10000);
            if (roundedTimes.contains(roundedTime)) {
                return this.next();
            } else {
                roundedTimes.add(roundedTime);
                return found;
            }
        } else {
            return null;
        }
    }

}
